package stone926.mods.more_enchantments.spawn;

import net.minecraft.enchantment.Enchantment;
import org.apache.commons.lang3.tuple.ImmutableTriple;
import org.apache.commons.lang3.tuple.Triple;
import stone926.mods.more_enchantments.enchantments.cleanUp.AbstractCleanUpEnchantment;
import stone926.mods.more_enchantments.util.RandomUtil;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import static net.minecraft.enchantment.Enchantments.*;
import static stone926.mods.more_enchantments.MoreEnchantmentsMod.*;

/**
 * Triple<Integer, Integer, Double>
 * -> 最低等级，最高等级，附魔几率
 */
public final class MobEnchantmentMaps {

  private static final HashMap<Enchantment, Triple<Integer, Integer, Double>> WITHER_SKULL_BOW = new HashMap<>() {{
    put(WITHER_SKULL_SHOOTER, new ImmutableTriple<>(1, WITHER_SKULL_SHOOTER.getMaxLevel(), 0.9));
    put(UNBREAKABLE, new ImmutableTriple<>(1, UNBREAKABLE.getMaxLevel(), 0.1));
  }};

  private static final HashMap<Enchantment, Triple<Integer, Integer, Double>> FIREBALL_BOW = new HashMap<>() {{
    put(RANDOM_FIREBALL_SHOOTER, new ImmutableTriple<>(1, RANDOM_FIREBALL_SHOOTER.getMaxLevel(), 0.9));
    put(UNBREAKABLE, new ImmutableTriple<>(1, UNBREAKABLE.getMaxLevel(), 0.1));
  }};

  private static final HashMap<Enchantment, Triple<Integer, Integer, Double>> SHULKER_BOW = new HashMap<>() {{
    put(SHULKER_BULLET_SHOOTER, new ImmutableTriple<>(1, SHULKER_BULLET_SHOOTER.getMaxLevel() - 1, 0.8));
    put(UNBREAKABLE, new ImmutableTriple<>(1, UNBREAKABLE.getMaxLevel(), 0.1));
  }};

  private final static Map<Enchantment, Triple<Integer, Integer, Double>> ARMOR = new HashMap<>() {{
    put(PROTECTION, new ImmutableTriple<>(1, PROTECTION.getMaxLevel() + 3, 1D));
    put(FATE, new ImmutableTriple<>(1, FATE.getMaxLevel(), 0.6D));
    put(DAMAGE_BLOCKING, new ImmutableTriple<>(1, 2, 0.6D));
    put(PROJECTILE_PROTECTION, new ImmutableTriple<>(1, PROJECTILE_PROTECTION.getMaxLevel() + 5, 1D));
    put(FIRE_PROTECTION, new ImmutableTriple<>(1, FIRE_PROTECTION.getMaxLevel() + 2, 1D));
    put(BLAST_PROTECTION, new ImmutableTriple<>(1, BLAST_PROTECTION.getMaxLevel() + 2, 1D));
    put(FEATHER_FALLING, new ImmutableTriple<>(1, FEATHER_FALLING.getMaxLevel() + 2, 1D));
    put(THORNS, new ImmutableTriple<>(7, THORNS.getMaxLevel() + 20, 1D));
    put(UNBREAKING, new ImmutableTriple<>(1, UNBREAKING.getMaxLevel(), 1D));
    put(MENDING, new ImmutableTriple<>(1, MENDING.getMaxLevel(), 1D));
    put(TEN_THOUSAND_ARROWS_AT_TARGET, new ImmutableTriple<>(1, TEN_THOUSAND_ARROWS_AT_SHOOTER.getMaxLevel(), 1D));
    put(BOMB, new ImmutableTriple<>(1, BOMB.getMaxLevel() + 2, 0.25));
    put(UNBREAKABLE, new ImmutableTriple<>(1, UNBREAKABLE.getMaxLevel(), 0.1));
    put(SOUL_SPEED, new ImmutableTriple<>(1, SOUL_SPEED.getMaxLevel(), 0.1));
    put(PURGE, new ImmutableTriple<>(1, 1, 0.1));
  }};

  private static final Map<Enchantment, Triple<Integer, Integer, Double>> WEAPON = new HashMap<>() {{
    put(HUNGER_ENCHANTMENT, new ImmutableTriple<>(1, HUNGER_ENCHANTMENT.getMaxLevel() + 2, 1D));
    put(WEAKNESS_ENCHANTMENT, new ImmutableTriple<>(1, WEAKNESS_ENCHANTMENT.getMaxLevel(), 1D));
    put(BLINDNESS_ENCHANTMENT, new ImmutableTriple<>(1, BLINDNESS_ENCHANTMENT.getMaxLevel(), 0.6D));
    put(SHARPNESS, new ImmutableTriple<>(1, SHARPNESS.getMaxLevel() + 6, 1D));
    put(SMITE, new ImmutableTriple<>(1, SMITE.getMaxLevel() + 5, 1D));
    put(BANE_OF_ARTHROPODS, new ImmutableTriple<>(1, BANE_OF_ARTHROPODS.getMaxLevel() + 5, 1D));
    put(KNOCKBACK, new ImmutableTriple<>(1, KNOCKBACK.getMaxLevel() + 3, 1D));
    put(FIRE_ASPECT, new ImmutableTriple<>(1, FIRE_ASPECT.getMaxLevel() + 2, 1D));
    put(MENDING, new ImmutableTriple<>(1, MENDING.getMaxLevel(), 1D));
    put(THUMP, new ImmutableTriple<>(1, THUMP.getMaxLevel() + 2, 1D));
    put(ONSLAUGHT, new ImmutableTriple<>(1, ONSLAUGHT.getMaxLevel() + 1, 0.4));
    put(UNBREAKABLE, new ImmutableTriple<>(1, UNBREAKABLE.getMaxLevel(), 0.05));
    put(VILLAGER_DEFENDER, new ImmutableTriple<>(1, VILLAGER_DEFENDER.getMaxLevel(), 1D));
    put(STARVE, new ImmutableTriple<>(1, 1, 0.6D));
  }};

  private static final Map<Enchantment, Triple<Integer, Integer, Double>> ZOMBIFIED_PIGLIN_WEAPON = new HashMap<>() {{
    put(HUNGER_ENCHANTMENT, new ImmutableTriple<>(1, HUNGER_ENCHANTMENT.getMaxLevel() + 2, 1D));
    put(WEAKNESS_ENCHANTMENT, new ImmutableTriple<>(1, WEAKNESS_ENCHANTMENT.getMaxLevel(), 1D));
    put(BLINDNESS_ENCHANTMENT, new ImmutableTriple<>(1, BLINDNESS_ENCHANTMENT.getMaxLevel(), 0.5D));
    put(SLOWNESS_ENCHANTMENT, new ImmutableTriple<>(1, 3, 0.4));
    put(SHARPNESS, new ImmutableTriple<>(1, SHARPNESS.getMaxLevel() + 6, 1D));
    put(KNOCKBACK, new ImmutableTriple<>(1, KNOCKBACK.getMaxLevel() + 3, 1D));
    put(FIRE_ASPECT, new ImmutableTriple<>(1, FIRE_ASPECT.getMaxLevel() + 2, 1D));
    put(MENDING, new ImmutableTriple<>(1, MENDING.getMaxLevel(), 1D));
    put(THUMP, new ImmutableTriple<>(2, THUMP.getMaxLevel() + 2, 1D));
    put(ONSLAUGHT, new ImmutableTriple<>(1, ONSLAUGHT.getMaxLevel() + 1, 0.4));
    put(UNBREAKABLE, new ImmutableTriple<>(1, UNBREAKABLE.getMaxLevel(), 0.05));
    put(STARVE, new ImmutableTriple<>(1, 1, 0.6D));
  }};

  private static final Map<Enchantment, Triple<Integer, Integer, Double>> SKELETON_WEAPON = new HashMap<>() {{
    put(SHARPNESS, new ImmutableTriple<>(6, SHARPNESS.getMaxLevel() + 9, 1D));
    put(KNOCKBACK, new ImmutableTriple<>(1, KNOCKBACK.getMaxLevel() + 2, 1D));
    put(FIRE_ASPECT, new ImmutableTriple<>(2, FIRE_ASPECT.getMaxLevel() + 4, 1D));
    put(SLOWNESS_ENCHANTMENT, new ImmutableTriple<>(1, SLOWNESS_ENCHANTMENT.getMaxLevel() + 1, 0.8D));
    put(WEAKNESS_ENCHANTMENT, new ImmutableTriple<>(1, WEAKNESS_ENCHANTMENT.getMaxLevel(), 1D));
    put(BLINDNESS_ENCHANTMENT, new ImmutableTriple<>(1, BLINDNESS_ENCHANTMENT.getMaxLevel(), 1D));
    put(WITHER_ENCHANTMENT, new ImmutableTriple<>(1, WITHER_ENCHANTMENT.getMaxLevel() + 1, 1D));
    put(HUNGER_ENCHANTMENT, new ImmutableTriple<>(1, HUNGER_ENCHANTMENT.getMaxLevel() + 2, 1D));
    put(UNBREAKABLE, new ImmutableTriple<>(1, UNBREAKABLE.getMaxLevel() + 2, 1D));
    put(ARMOR_BREAKING, new ImmutableTriple<>(1, ARMOR_BREAKING.getMaxLevel() + 3, 1D));
    put(STARVE, new ImmutableTriple<>(1, 1, 1D));
  }};

  private static final Map<Enchantment, Triple<Integer, Integer, Double>> TOOL = new HashMap<>() {{
    put(EFFICIENCY, new ImmutableTriple<>(1, 100, 0.9));
    put(UNBREAKING, new ImmutableTriple<>(1, UNBREAKING.getMaxLevel() + 3, 1D));
    put(MENDING, new ImmutableTriple<>(1, 1, 0.4));
    put(UNBREAKABLE, new ImmutableTriple<>(1, 1, 0.1));
    put(DESTROY_CURSE, new ImmutableTriple<>(1, DESTROY_CURSE.getMaxLevel(), 0.3));
    put(MULTIPLY_CURSE, new ImmutableTriple<>(1, MULTIPLY_CURSE.getMaxLevel(), 0.2));
  }};

  private static final Map<Enchantment, Triple<Integer, Integer, Double>> WITHER_SKELETON_WEAPON = new HashMap<>() {{
    put(SHARPNESS, new ImmutableTriple<>(5, 30, 1D));
    put(FIRE_ASPECT, new ImmutableTriple<>(1, FIRE_ASPECT.getMaxLevel() + 5, 1D));
    put(UNBREAKABLE, new ImmutableTriple<>(1, UNBREAKABLE.getMaxLevel(), 0.1));
    put(VAMPIRE, new ImmutableTriple<>(1, VAMPIRE.getMaxLevel(), 0.8));
    put(DECAPITATION, new ImmutableTriple<>(1, 5, 0.4));
  }};

  private static final Map<Enchantment, Triple<Integer, Integer, Double>> CROSSBOW = new HashMap<>() {{
    put(MULTISHOT, new ImmutableTriple<>(1, 1, 1D));
    put(QUICK_CHARGE, new ImmutableTriple<>(1, 5, 1D));
    put(PIERCING, new ImmutableTriple<>(1, PIERCING.getMaxLevel() * 2, 1D));
    put(UNBREAKING, new ImmutableTriple<>(1, UNBREAKING.getMaxLevel() + 1, 0.9));
    put(FLASH, new ImmutableTriple<>(1, 5, 1D));
    put(STRAFING, new ImmutableTriple<>(1, 6, 0.3));
  }};

  private static final Map<Enchantment, Triple<Integer, Integer, Double>> TRIDENT = new HashMap<>() {{
    put(THUNDER, new ImmutableTriple<>(1, 1, 0.3));
    put(THUMP, new ImmutableTriple<>(3, 7, 1D));
    put(SHARPNESS, new ImmutableTriple<>(5, 7, 1D));
    put(LOYALTY, new ImmutableTriple<>(5, 30, 1D));
    put(IMPALING, new ImmutableTriple<>(5, 20, 1D));
    put(UNBREAKABLE, new ImmutableTriple<>(1, 1, 0.1));
    put(VAMPIRE, new ImmutableTriple<>(1, VAMPIRE.getMaxLevel() + 1, 0.8));
    put(TRACTION, new ImmutableTriple<>(1, 3, 0.3));
  }};

  private static final Map<Enchantment, Triple<Integer, Integer, Double>> TURTLE_HELMET = new HashMap<>() {{
    put(PROTECTION, new ImmutableTriple<>(1, 30, 1D));
    put(PURGE, new ImmutableTriple<>(1, 9, 1D));
    put(TEN_THOUSAND_ARROWS_AT_TARGET, new ImmutableTriple<>(1, 7, 0.25D));
    put(TEN_THOUSAND_ARROWS_AT_SHOOTER, new ImmutableTriple<>(1, 7, 0.25D));
    put(FIRE_PROTECTION, new ImmutableTriple<>(1, 20, 0.6D));
    put(UNBREAKABLE, new ImmutableTriple<>(1, 1, 0.35));
  }};

  private static final Map<Enchantment, Triple<Integer, Integer, Double>> WITCH_ARMOR = new HashMap<>() {{
    put(PROTECTION, new ImmutableTriple<>(1, 15, 0.9D));
    put(PURGE, new ImmutableTriple<>(1, 9, 0.6D));
    put(FATE, new ImmutableTriple<>(1, 20, 0.6D));
    put(DAMAGE_BLOCKING, new ImmutableTriple<>(1, 6, 0.9D));
    put(RETALIATION, new ImmutableTriple<>(1, 6, 0.7D));
  }};

  public static Map<Enchantment, Triple<Integer, Integer, Double>> BOW(Random random) {
    return new HashMap<>() {{
      put(POWER, new ImmutableTriple<>(4, POWER.getMaxLevel() + 12, 1D));
      if (random.nextInt(3) > 0) {
        put(PUNCH, new ImmutableTriple<>(1, PUNCH.getMaxLevel() + 5, 0.9));
      } else {
        put(TRACTION, new ImmutableTriple<>(2, TRACTION.getMaxLevel() + 5, 0.9));
      }
      put(FLAME, new ImmutableTriple<>(1, FLAME.getMaxLevel(), 0.9));
      put(UNBREAKING, new ImmutableTriple<>(1, UNBREAKING.getMaxLevel(), 0.9));
    }};
  }

  public static Map<Enchantment, Triple<Integer, Integer, Double>> WITHER_SKULL_BOW() {
    return WITHER_SKULL_BOW;
  }

  public static Map<Enchantment, Triple<Integer, Integer, Double>> FIREBALL_BOW() {
    return FIREBALL_BOW;
  }

  public static Map<Enchantment, Triple<Integer, Integer, Double>> SHULKER_BOW() {
    return SHULKER_BOW;
  }

  public static Map<Enchantment, Triple<Integer, Integer, Double>> ARMOR(Random random) {
    return new HashMap<>(ARMOR) {{
      put(RETALIATION, new ImmutableTriple<>(1, RandomUtil.nextInt(3, 5, random), 0.03));
    }};
  }

  public static Map<Enchantment, Triple<Integer, Integer, Double>> WEAPON() {
    return WEAPON;
  }

  public static Map<Enchantment, Triple<Integer, Integer, Double>> ZOMBIFIED_PIGLIN_WEAPON() {
    return ZOMBIFIED_PIGLIN_WEAPON;
  }

  public static Map<Enchantment, Triple<Integer, Integer, Double>> SKELETON_WEAPON() {
    return SKELETON_WEAPON;
  }

  public static Map<Enchantment, Triple<Integer, Integer, Double>> TOOL(Random random) {
    return new HashMap<>(TOOL) {{
      if (random.nextBoolean()) {
        put(FORTUNE, new ImmutableTriple<>(1, FORTUNE.getMaxLevel() * 2, 1D));
      } else {
        put(SILK_TOUCH, new ImmutableTriple<>(1, 1, 1D));
      }
      List<AbstractCleanUpEnchantment> list = stone926.mods.more_enchantments.util.EnchantmentUtil.CLEAN_UP_ENCHANTMENTS;
      AbstractCleanUpEnchantment cleanUpEnchantment = list.get(random.nextInt(list.size()));
      put(cleanUpEnchantment, new ImmutableTriple<>(1, cleanUpEnchantment.getMaxLevel() + 1, 0.5));
    }};
  }

  public static Map<Enchantment, Triple<Integer, Integer, Double>> WITHER_SKELETON_WEAPON() {
    return WITHER_SKELETON_WEAPON;
  }

  public static Map<Enchantment, Triple<Integer, Integer, Double>> CROSSBOW() {
    return CROSSBOW;
  }

  public static Map<Enchantment, Triple<Integer, Integer, Double>> TRIDENT() {
    return TRIDENT;
  }

  public static Map<Enchantment, Triple<Integer, Integer, Double>> TURTLE_HELMET() {
    return TURTLE_HELMET;
  }

  public static Map<Enchantment, Triple<Integer, Integer, Double>> WITCH_ARMOR() {
    return WITCH_ARMOR;
  }

}
